本日的重點就是介紹個人所使用的Containerized Development框架,說穿了就是分享個人所使用的DockerFile與Docker Compose設定檔。
Docker是一套現在非常火紅、以容器為基礎的虛擬化框架,但比起傳統的虛擬機器使,使用上也十分的輕易近人,而且更重要的是有許多第三方已經建立好的Image,可以直接pull下來做使用,也算是一種站在巨人肩膀上的方式。Docker Compose則是一種使用Docker時的設置檔案,主要用來簡化Docker的使用方式以及再利用性。詳細就不多做介紹,建議可以直接參考官方文件:
談這件事之前想先問下列兩種讀者問題:
其實這兩個問題都環繞著一個相同的核心,就是模型的再現性問題。而再現性又可以分兩個層面:
而 Containerized Development 便是一個對這兩種再現性都具有相當程度幫助的一個方式。(當然也有例外就是,但就是後話了)
https://github.com/SraRod/iThome2022/tree/aa33395073d0e0dbf3321521f08415c41fbd7d9a
(註:原則上這幾個檔案應該會持續更新,各位也可以選擇main的最新檔案)
Docker基本上在做的事情就是把已經建立好的Image,展開成一個Container再來運行。
而DockerFile的作用,基本上就是用來製作我們自己需要的Image!
可以參考我在連結中的DockerFile
首先我們一樣站在巨人的肩膀上,運用MONAI所提供的Image作為基礎
FROM projectmonai/monai:0.9.1
但實際使用會發現這位巨人的視力好像有點狀況,於是重裝一下opencv。
(註:應該是因為MONAI大部分都用PIL,所以裡頭沒有OPENCV)
(註:也可以在requirement裡面裝 opencv-headless,比較方便但Performance上有些許差異,看個人抉擇)
# install opencv dependency
RUN apt update &&\
apt install libgl1-mesa-glx -y &&\
conda install -c conda-forge nodejs=16.12.0 -y
# for nodejs > 12...
接著則是利用requirements.txt安裝裡頭Python所需要的套件以及固定好的版本。
# specify version if you could...
COPY requirements.txt .
# install pyton dependency
RUN pip install --upgrade pip &&\
pip install -r requirements.txt
最後就是同步一下內外跟專案的Python路徑,會讓一些小操作上更加順暢。就大功告成啦!
# set workspace to python path
ENV PYTHONPATH $PYTHONPATH
下一步則是 docker-compose
的設定檔,請參考我寫好的檔案。
首先介紹一下,以下是基礎設定,解說寫在後面
version: '3.7' # 採用的Confiuguration版本
services:
jupyter:
container_name: "iThome2022" # build起來以後的container name,沒有也可以,會根據資料夾跟service name自己命名
build: . # 根據我們剛剛建立好的Dockerfile來build Image,預設檔名就是Dockerfile,可以不同,需加額外參數
shm_size: '32GB' # Share Memory的設定,太低的話,PyTorch有些操作會出錯
runtime: nvidia # 讓Container可以吃到NVIDIA的GPU
user: root # 用root權限執行
working_dir: /home/$USER/workspace # 設定workspace
environment: # 一些環境變數,基本上跟在LINUX相同
NVIDIA_VISIBLE_DEVICES: 0 # 只吃第一張 GPU ,跟同事同主機多張GPU怕誤搶到時可以使用
JUPYTER_ENABLE_LAB: 'yes' # 把Jupyter LAB 打開
PYTHONPATH: /home/$USER/workspace # 同working_dir
這裡則是把container內部的空間作一個連動,類似ln -s
。
值得注意的是除了把repo的資料夾就投到workspace以外,這裡還分別做了與local user共享ssh key、git設定檔以及把jupyter放到外部的小巧思。可以讓使用者直接打開jupyter lab開發的時候更加順暢一些。
volumes:
- .:/home/$USER/workspace
- ~/.ssh:/home/$USER/.ssh # for ssh
- ~/.gitconfig:/home/$USER/.gitconfig # for git
- ./.jupyter:/root/.jupyter
這邊就是port跟外部的連動,我是都會把juyter用的8888打到5566(得第一,不解釋)。
5000就是預留給額外服務用的,例如開發很常用到的Tensorboard 或是 MLFlow。
ports:
- 5566:8888
- 5000:5000
最後則是container建立好以後,需要執行的指令。這邊主要就是作jupyter的一些初始設定,然後再把服務架起來(以危險的方式,好孩子在佈署非個人化的服務時千萬不要學)。
command: bash -c '
cd /home/$USER/workspace
&& jupyter lab build
&& jupyter labextension install jupyterlab-plotly
&& jupyter labextension install @jupyter-widgets/jupyterlab-manager
&& jupyter lab --no-browser --allow-root --ip=0.0.0.0 --ContentsManager.allow_hidden=True --NotebookApp.token="" --NotebookApp.password=""'
基本上就是把整個repo clone下來以後
docker-compose up -d
等待image拉下來跟build好以後,就是一套完整可以使用的jupyter lab啦!